---
title: "核心语法与结构对比"
description: "从 JavaScript 视角学习 Rust 基础语法，包括变量声明、数据类型、控制流和函数定义"
---

# 核心语法与结构对比

## 📖 学习目标

通过对比 JavaScript 和 Rust 的基础语法，快速掌握 Rust 的核心概念。我们将从你熟悉的 JavaScript 语法出发，逐步引入 Rust 的语法特性。

---

## 🎯 变量声明与作用域

在 JavaScript 中，我们使用 `var`、`let` 和 `const` 来声明变量：

<UniversalEditor title="JavaScript 变量声明" compare={true}>
```javascript !! js
// JavaScript 变量声明
var oldWay = "不推荐使用";
let mutableVar = "可以重新赋值";
const immutableVar = "不能重新赋值";

// 变量可以重新赋值
mutableVar = "新的值";
console.log(mutableVar); // 输出: 新的值

// const 声明的变量不能重新赋值
// immutableVar = "尝试修改"; // 这会报错
```
```rust !! rs
fn main() {
    // Rust 变量声明
    let immutable_var = "默认不可变";
    let mut mutable_var = "可以重新赋值"; // 需要 mut 关键字

    // 可变变量可以重新赋值
    mutable_var = "新的值";
    println!("{}", mutable_var); // 输出: 新的值

    // 不可变变量不能重新赋值
    // immutable_var = "尝试修改"; // 编译错误！

    // 变量遮蔽（shadowing）- Rust 特有概念
    let x = 5;
    let x = x + 1; // 创建新的变量 x，遮蔽原来的 x
    println!("x = {}", x); // 输出: x = 6
}
```
</UniversalEditor>

### 关键差异

1. **默认不可变性**: Rust 中变量默认不可变，需要 `mut` 关键字才能修改
2. **变量遮蔽**: Rust 允许在同一作用域内重新声明同名变量
3. **类型推导**: Rust 编译器可以自动推导变量类型

---

## 📊 基本数据类型对比

<UniversalEditor title="JavaScript 数据类型" compare={true}>
```javascript !! js
// JavaScript 是动态类型语言
// JavaScript 基本数据类型
let number = 42;           // Number
let string = "Hello";      // String
let boolean = true;        // Boolean
let array = [1, 2, 3];     // Array
let object = {name: "Rust"}; // Object
let nullValue = null;      // null
let undefinedValue;        // undefined

// 类型检查
console.log(typeof number);        // "number"
console.log(typeof string);        // "string"
console.log(typeof boolean);       // "boolean"
console.log(Array.isArray(array)); // true
```

```rust !! rs
fn main() {
    // Rust 是静态类型语言，类型在编译时确定
    // Rust 基本数据类型
    let integer: i32 = 42;           // 32位有符号整数
    let unsigned: u32 = 42;          // 32位无符号整数
    let float: f64 = 3.14;           // 64位浮点数
    let boolean: bool = true;        // 布尔值
    let character: char = 'A';       // Unicode 字符
    let string: String = String::from("Hello"); // 字符串
    let string_slice: &str = "World"; // 字符串切片

    // 数组 - 固定长度
    let array: [i32; 5] = [1, 2, 3, 4, 5];

    // 元组 - 可以包含不同类型
    let tuple: (i32, f64, &str) = (500, 6.4, "hello");

    // 访问数组和元组元素
    println!("数组第一个元素: {}", array[0]);
    println!("元组第一个元素: {}", tuple.0);
}
```
</UniversalEditor>

### 类型系统差异

1. **静态 vs 动态**: Rust 在编译时检查类型，JavaScript 在运行时检查
2. **整数类型**: Rust 有多种整数类型（i8, i16, i32, i64, u8, u16, u32, u64）
3. **字符串**: Rust 区分 `String`（拥有所有权）和 `&str`（借用）

---

## 🔄 控制流对比

<UniversalEditor title="JavaScript 控制流" compare={true}>
```javascript !! js
// JavaScript 条件语句
let age = 18;

if (age >= 18) {
    console.log("成年人");
} else if (age >= 12) {
    console.log("青少年");
} else {
    console.log("儿童");
}

// switch 语句
let day = "Monday";
switch (day) {
    case "Monday":
        console.log("星期一");
        break;
    case "Tuesday":
        console.log("星期二");
        break;
    default:
        console.log("其他日子");
}

// 循环
for (let i = 0; i < 5; i++) {
    console.log(i);
}

let numbers = [1, 2, 3, 4, 5];
for (let num of numbers) {
    console.log(num);
}
```

```rust !! rs
fn main() {
    // Rust 条件语句
    let age = 18;

    if age >= 18 {
        println!("成年人");
    } else if age >= 12 {
        println!("青少年");
    } else {
        println!("儿童");
    }

    // if 是表达式，可以赋值
    let status = if age >= 18 { "成年人" } else { "未成年人" };
    println!("状态: {}", status);

    // match 语句（类似 switch，但更强大）
    let day = "Monday";
    match day {
        "Monday" => println!("星期一"),
        "Tuesday" => println!("星期二"),
        _ => println!("其他日子"), // _ 是通配符
    }

    // 循环
    for i in 0..5 {
        println!("{}", i);
    }

    let numbers = vec![1, 2, 3, 4, 5];
    for num in &numbers {
        println!("{}", num);
    }

    // while 循环
    let mut count = 0;
    while count < 5 {
        println!("count: {}", count);
        count += 1;
    }

    // loop 循环（无限循环）
    let mut counter = 0;
    loop {
        counter += 1;
        if counter > 5 {
            break; // 跳出循环
        }
        println!("counter: {}", counter);
    }
}
```
</UniversalEditor>

### 控制流差异

1. **if 表达式**: Rust 的 `if` 可以返回值，用于赋值
2. **match 语句**: 比 JavaScript 的 `switch` 更强大，支持模式匹配
3. **循环语法**: Rust 使用 `for in` 语法，更简洁

---

## 🏗️ 函数定义对比

<UniversalEditor title="JavaScript 函数定义" compare={true}>
```javascript !! js
// JavaScript 函数定义
function greet(name) {
    return `Hello, ${name}!`;
}

// 箭头函数
const greetArrow = (name) => {
    return `Hello, ${name}!`;
};

// 简化的箭头函数
const greetSimple = name => `Hello, ${name}!`;

// 函数调用
console.log(greet("Rust"));        // Hello, Rust!
console.log(greetArrow("Rust"));   // Hello, Rust!
console.log(greetSimple("Rust"));  // Hello, Rust!

// 默认参数
function greetWithDefault(name = "World") {
    return `Hello, ${name}!`;
}

console.log(greetWithDefault());     // Hello, World!
console.log(greetWithDefault("Rust")); // Hello, Rust!
```

```rust !! rs

fn main() {
    // Rust 函数定义
    fn greet(name: &str) -> String {
        format!("Hello, {}!", name)
    }

    // 函数调用
    println!("{}", greet("Rust")); // Hello, Rust!

    // 默认参数（通过 Option 实现）
    fn greet_with_default(name: Option<&str>) -> String {
        let name = name.unwrap_or("World");
        format!("Hello, {}!", name)
    }

    println!("{}", greet_with_default(None));        // Hello, World!
    println!("{}", greet_with_default(Some("Rust"))); // Hello, Rust!

    // 多个参数
    fn add(a: i32, b: i32) -> i32 {
        a + b // 最后一个表达式是返回值，不需要 return
    }

    println!("{}", add(5, 3)); // 8

    // 函数作为表达式
    fn get_status(age: i32) -> &'static str {
        if age >= 18 {
            "成年人"
        } else {
            "未成年人"
        }
    }

    println!("{}", get_status(20)); // 成年人
}
```
</UniversalEditor>

### 函数差异

1. **类型注解**: Rust 需要为参数和返回值指定类型
2. **返回值**: Rust 函数的最后一个表达式自动作为返回值
3. **默认参数**: Rust 通过 `Option` 类型实现默认参数
4. **函数签名**: Rust 的函数签名更明确，有助于编译时检查

---

## 🎭 闭包对比

<UniversalEditor title="JavaScript 闭包" compare={true}>
```javascript !! js
// JavaScript 闭包
function createCounter() {
    let count = 0;
    return function() {
        count += 1;
        return count;
    };
}

const counter = createCounter();
console.log(counter()); // 1
console.log(counter()); // 2
console.log(counter()); // 3

// 箭头函数闭包
const add = (a) => (b) => a + b;
const addFive = add(5);
console.log(addFive(3)); // 8

// 闭包捕获外部变量
let multiplier = 2;
const multiply = (x) => x * multiplier;
console.log(multiply(5)); // 10

multiplier = 3;
console.log(multiply(5)); // 15
```

```rust !! rs
fn main() {
    // Rust 闭包
    fn create_counter() -> impl FnMut() -> i32 {
        let mut count = 0;
        move || {
            count += 1;
            count
        }
    }

    let mut counter = create_counter();
    println!("{}", counter()); // 1
    println!("{}", counter()); // 2
    println!("{}", counter()); // 3

    // 闭包语法
    let add = |a, b| a + b;
    println!("{}", add(5, 3)); // 8

    // 捕获外部变量
    let multiplier = 2;
    let multiply = |x| x * multiplier;
    println!("{}", multiply(5)); // 10

    // 闭包类型注解
    let expensive_closure = |num: u32| -> u32 {
        println!("计算中...");
        num * 2
    };

    println!("{}", expensive_closure(5)); // 计算中... 10

    // 迭代器中使用闭包
    let numbers = vec![1, 2, 3, 4, 5];
    let doubled: Vec<i32> = numbers.iter().map(|x| x * 2).collect();
    println!("{:?}", doubled); // [2, 4, 6, 8, 10]
}
```
</UniversalEditor>

### 闭包差异

1. **语法**: Rust 闭包使用 `|参数|` 语法
2. **所有权**: Rust 闭包需要考虑所有权和借用
3. **类型推导**: Rust 编译器可以推导闭包类型
4. **迭代器**: Rust 闭包与迭代器结合使用更自然

---

## 🎯 练习题

### 练习 1: 变量声明转换

将以下 JavaScript 代码转换为 Rust 代码：
<UniversalEditor title="练习 1: 变量声明转换" compare={true}>
```javascript !! js
let name = "LangShift";
let age = 25;
let isStudent = true;
let scores = [85, 90, 78, 92];
```
</UniversalEditor>

<details>
<summary>查看答案</summary>

<UniversalEditor title="练习 1: 变量声明转换" compare={true}>
```rust !! rs
fn main() {
    let name = "LangShift";
    let age: i32 = 25;
    let is_student: bool = true;
    let scores: [i32; 4] = [85, 90, 78, 92];
}
```
</UniversalEditor>

</details>

### 练习 2: 函数转换

将以下 JavaScript 函数转换为 Rust 函数：

<UniversalEditor title="练习 2: 函数转换" compare={true}>
```javascript !! js
function calculateArea(width, height) {
    return width * height;
}

function isAdult(age) {
    return age >= 18;
}
```
</UniversalEditor>

<details>
<summary>查看答案</summary>

<UniversalEditor title="练习 2: 函数转换" compare={true}>
```rust !! rs
fn main() {
    fn calculate_area(width: f64, height: f64) -> f64 {
        width * height
    }

    fn is_adult(age: i32) -> bool {
        age >= 18
    }
}
```
</UniversalEditor>

</details>

### 练习 3: 控制流转换

将以下 JavaScript 代码转换为 Rust 代码：

<UniversalEditor title="练习 3: 控制流转换" compare={true}>
```javascript !! js
let grade = 85;
let result;

if (grade >= 90) {
    result = "优秀";
} else if (grade >= 80) {
    result = "良好";
} else if (grade >= 70) {
    result = "中等";
} else {
    result = "需要努力";
}
```
</UniversalEditor>

<details>
<summary>查看答案</summary>

<UniversalEditor title="练习 3: 控制流转换" compare={true}>
```rust !! rs       
fn main() {
    let grade = 85;
    let result = if grade >= 90 {
        "优秀"
    } else if grade >= 80 {
        "良好"
    } else if grade >= 70 {
        "中等"
    } else {
        "需要努力"
    };
}
```
</UniversalEditor>

</details>

---

## 📝 总结

在这一章中，我们学习了：

1. **变量声明**: Rust 默认不可变，需要 `mut` 关键字才能修改
2. **数据类型**: Rust 是静态类型语言，类型在编译时确定
3. **控制流**: Rust 的 `if` 是表达式，`match` 比 `switch` 更强大
4. **函数**: Rust 需要类型注解，最后一个表达式是返回值
5. **闭包**: Rust 闭包语法简洁，需要考虑所有权

### 关键要点

- Rust 的语法更严格，但提供了更好的安全性和性能
- 从 JavaScript 迁移到 Rust 需要适应静态类型系统
- Rust 的所有权系统将在后续章节中详细介绍
- 多练习，多对比，逐步适应 Rust 的编程思维

在下一章中，我们将学习 Rust 的模块系统和包管理，了解如何组织和管理 Rust 项目。

---

**继续学习**: [模块系统与构建工具](./module-02-module-system) 